package cn.tworice.log.service;

import cn.tworice.common.util.StringUtils;
import cn.tworice.log.dao.LoginLogDao;
import cn.tworice.log.dao.po.OperationLogDO;
import cn.tworice.log.dao.po.LoginLogDO;
import cn.tworice.log.dao.LogDao;
import cn.tworice.mybatis.query.LambdaQueryWrapperX;
import cn.tworice.mybatis.query.MPJLambdaWrapperX;
import cn.tworice.mybatis.vo.PageParam;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 异步提交日志信息，以尽量少的影响主进程
 * @author 二饭
 */
@Service
@EnableAsync
@Transactional
public class LogService extends ServiceImpl<LogDao, OperationLogDO> {

    @Resource
    private LogDao logDao;

    @Resource
    private LoginLogDao loginLogDao;

    @Async
    public void addAdminLog(OperationLogDO log) {
        logDao.insert(log);
    }

    /**
     * 获取操作日志
     */
    public Map<String,Object> getPage(PageParam pageParam, OperationLogDO entity) {
        return logDao.selectPage(pageParam, new MPJLambdaWrapperX<OperationLogDO>()
                .eqIfPresent(OperationLogDO::getUserId, entity.getUserId())
                .orderByDesc(OperationLogDO::getCreateTime)
        );
    }

    /**
     * 获取登录日志分页数据
     * @param pageParam 分页参数
     * @param entity 查询条件
     * @return 分页数据
     */
    public Map<String, Object> getLoginLogPage(PageParam pageParam,LoginLogDO entity) {
        return loginLogDao.selectPage(pageParam, new LambdaQueryWrapperX<LoginLogDO>()
                .eqIfPresent(LoginLogDO::getLoginName, entity.getLoginName())
                .orderByDesc(LoginLogDO::getCreateTime)
        );
    }

    /**
     * 添加登录日志
     * @param loginLog 登录日志
     */
    @Async
    public void addLoginLog(LoginLogDO loginLog) {
        loginLog.setCreateTime(System.currentTimeMillis());
        loginLog.setId(StringUtils.generateUuid());
        loginLogDao.insert(loginLog);
    }

    /**
     * 根据操作日志恢复数据
     * @param id 操作日志ID
     * @return 是否恢复成功
     */
    public String recover(String id) {
        OperationLogDO log = logDao.selectById(id);
        log.setActive("【已恢复】"+log.getActive());
        if(this.undeleted(log)) {
            log.setTableName(null);
            if (logDao.update(new LambdaUpdateWrapper<OperationLogDO>()
                    .eq(OperationLogDO::getId, id)
                    .set(OperationLogDO::getActive, log.getActive())
                    .set(OperationLogDO::getTableName, log.getTableName())
            ) == 0) {
                throw new RuntimeException("恢复失败");
            }
            return "恢复成功";
        }else {
            throw new RuntimeException("恢复失败");
        }
    }

    /**
     * 登录日志记录
     */
    @Deprecated
    @Async
    public void addLoginLog(String username, String password, int i) {
        LoginLogDO log = new LoginLogDO();
        log.setLoginName(username);
        log.setStatus(i);
        log.setPassWord(password);
        log.setCreateTime(System.currentTimeMillis());
        log.setId(StringUtils.generateUuid());
        loginLogDao.insert(log);
    }

    @Deprecated
    public void addLoginLog(String username, String password, int i, String ipAddr) {
        LoginLogDO log = new LoginLogDO();
        log.setLoginName(username);
        log.setStatus(i);
        log.setPassWord(password);
        log.setCreateTime(System.currentTimeMillis());
        log.setId(UUID.randomUUID().toString().replaceAll("-",""));
        log.setIpAddr(ipAddr);
        loginLogDao.insert(log);
    }

    /**
     * 执行指定的数据表恢复
     * @param operationLogDO 操作日志
     * @return 是否恢复成功
     */
    private boolean undeleted(OperationLogDO operationLogDO){
        StringBuilder s = new StringBuilder();
        JSONArray.parseArray(operationLogDO.getTargetId()).toJavaList(String.class).forEach(item->{
            s.append(",'").append(item).append("'");
        });
        return logDao.undeleted(operationLogDO.getTableName(), s.substring(1))>0;
    }


}
